Skip to content

Migrate all links to use getPath()#2821

Merged
NatSquared merged 11 commits intomainfrom
DEP-256-migrate-links-to-getpath
Apr 14, 2026
Merged

Migrate all links to use getPath()#2821
NatSquared merged 11 commits intomainfrom
DEP-256-migrate-links-to-getpath

Conversation

@NatSquared
Copy link
Copy Markdown
Collaborator

Issue #: 🎟️ DEP-255

Description of changes:

  • Feature Migrate all links to use getPath()
    • Updated all hardcoded links in the codebase to use the new getPath() function from routes/routes.ts, which generates URLs based on a centralized ROUTES constant. This ensures that all links are consistent and automatically updated if route paths change in the future.
    • This includes links in components, API calls, navigation, and anywhere else URLs are generated or used in the application.

User Guide update ticket (if applicable):

    • Yes, a user guide update ticket has been created. (Link to ticket)
    • No, a user guide update ticket is not required.

Common component changes:

    • Yes, I have updated CONTRIBUTING.md and the docblocks to document any changes to the common components.
    • No, there are no changes to the common components.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 14, 2026

Codecov Report

❌ Patch coverage is 73.58491% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.57%. Comparing base (82ee69c) to head (07f8bf4).

Files with missing lines Patch % Lines
web/src/components/engagement/listing/index.tsx 60.00% 4 Missing ⚠️
web/src/components/survey/listing/Surveys.tsx 55.55% 4 Missing ⚠️
...b/src/components/engagement/form/ActionContext.tsx 25.00% 3 Missing ⚠️
web/src/components/publicDashboard/Dashboard.tsx 81.25% 3 Missing ⚠️
...components/comments/admin/review/CommentReview.tsx 33.33% 2 Missing ⚠️
...rc/components/publicDashboard/DashboardContext.tsx 33.33% 2 Missing ⚠️
web/src/components/tenantManagement/Listing.tsx 50.00% 2 Missing ⚠️
web/src/services/engagementSlugService/index.tsx 0.00% 2 Missing ⚠️
...gement/admin/create/authoring/AuthoringSideNav.tsx 50.00% 1 Missing ⚠️
.../src/components/survey/listing/ActionsDropDown.tsx 66.66% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2821      +/-   ##
==========================================
+ Coverage   75.43%   75.57%   +0.14%     
==========================================
  Files         520      520              
  Lines       19874    19909      +35     
  Branches     1560     1573      +13     
==========================================
+ Hits        14992    15047      +55     
+ Misses       4875     4855      -20     
  Partials        7        7              
Flag Coverage Δ
web 62.58% <73.58%> (+0.37%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...nents/comments/admin/reviewListing/Submissions.tsx 85.41% <100.00%> (+0.31%) ⬆️
...rc/components/comments/admin/textListing/index.tsx 80.83% <100.00%> (+0.16%) ⬆️
...nt/admin/create/authoring/AuthoringNavElements.tsx 100.00% <100.00%> (ø)
.../components/engagement/listing/ActionsDropDown.tsx 81.70% <100.00%> (+9.48%) ⬆️
web/src/components/landing/EngagementTile.tsx 75.34% <100.00%> (ø)
...eb/src/components/layout/Header/InternalHeader.tsx 86.40% <100.00%> (+0.10%) ⬆️
web/src/components/layout/SideNav/SideNav.tsx 92.75% <100.00%> (ø)
.../src/components/layout/SideNav/SideNavElements.tsx 100.00% <100.00%> (ø)
web/src/components/layout/SideNav/UserGuideNav.tsx 93.75% <100.00%> (+0.41%) ⬆️
web/src/components/survey/report/SearchBar.tsx 82.35% <100.00%> (-0.99%) ⬇️
... and 21 more

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@jareth-whitney jareth-whitney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job streamlining our link system. It will be much easier to update our links in one place than to update all the individual links. Nothing blocking, just a few things to check out:

  • Consider validating the route params in your getPath() function to avoid value ?? ''
  • Awaits without suspense: probably fine, just a different pattern than what we've used
  • Path concat questions (is forward slash in the middle?)
  • Weird translation concat for prop (probably fine, just a weird translation implementation)
  • language vs language: language

<Grid size={12} mt={5}>
<FormProvider {...engagementCreationForm}>
<EngagementForm isNewEngagement onSubmit={onSubmit} />
<EngagementForm engagement={null} onSubmit={onSubmit} />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, one less unneeded prop.


const getTargetPreviewBasePath = () => `${getBasePathPrefix()}/engagements/${engagementId}/preview`;
const getTargetPreviewBasePath = () =>
`${getBasePathPrefix()}/${getPath(ROUTES.ADMIN_ENGAGEMENT_PREVIEW, { engagementId: engagementId ?? '' })}`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could simplify this line a bit if you validate the engagementId (or any other route params) within your getPath() function. Then you just need to use { engagementId } for the second arg.

style={{ position: 'relative', bottom: '4px' }}
/>
</IconButton>
<Await resolve={slug}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No suspense needed here?

const baseSurveyStatus = getStatusFromStatusId(loadedEngagement.submission_status);
const [currentPanel, setCurrentPanel] = React.useState('email');
const [isEmailModalOpen, setIsEmailModalOpen] = React.useState(false);
const languageId = sessionStorage.getItem('languageId') ?? language ?? AppConfig.language.defaultLanguageId;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a definition for sessionStorage and then discovered that it's equivalent to window.sessionStorage and is best practice, so all good!

// React Router context and navigate to a new base URL to pass the new
// tenant in the path and trigger a full reload of the app with the
// new tenant's context
href={`/${tenant.short_name}${getPath(ROUTES.HOME)}`}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking if the forward slash is automatically placed between tenant short name and the home route. I'm guessing it is automatically generated in getPath().

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes; getPath() returns a leading slash

</Grid>
<Grid sx={{ marginLeft: 'auto', marginRight: '32px' }}>
<Link onClick={UserService.doLogout} to={'#'}>
<Link onClick={UserService.doLogout} href={'#'}>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is the best way to do a self-link.

data-testid="link-container"
>
{translate('dashboard.link.0') + engagement.name + translate('dashboard.link.1')}
{translate('dashboard.link.0')} {engagement.name} {translate('dashboard.link.1')}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may require some explanation. It looks like we're constructing a link but the translation integration is a bit weird.

navigate(
getPath(ROUTES.PUBLIC_ENGAGEMENT_BY_SLUG, {
slug: slug.slug,
language: language,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just use language here, no need for language: language.

navigate(
getPath(ROUTES.PUBLIC_ENGAGEMENT_BY_SLUG, {
slug: slug.slug,
language: language,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here: language over language: language

export const getSlugByEngagementId = async (engagementId: number): Promise<GetSlugByEngagementIdResponse> => {
if (!engagementId || isNaN(Number(engagementId))) {
return Promise.reject('Invalid Slug' + engagementId);
return Promise.reject('Invalid ID' + engagementId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a space for the concat?

@NatSquared NatSquared merged commit 556ffd7 into main Apr 14, 2026
7 checks passed
@NatSquared NatSquared deleted the DEP-256-migrate-links-to-getpath branch April 14, 2026 20:50
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants